/**
 * 
 */
package com.manthano.applogin.authorization.service.impl;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.manthano.applogin.authorization.bo.UserRole;
import com.manthano.applogin.management.bo.AppUser;
import com.manthano.applogin.management.bo.LoginUser;
import com.manthano.applogin.management.dao.AppUserDao;
import com.manthano.applogin.management.data.RoleType;
import com.manthano.applogin.management.exception.UserException;
import com.manthano.applogin.management.service.AppUserService;
import com.manthano.scope.transaction.ORMTransactionManager;
import com.manthano.util.CallBack.CallBack;

/**
 * @author Dell
 */
public class AppUserServiceImpl extends ORMTransactionManager implements AppUserService
{
	private AppUserDao	appUserDao	= null;

	/**
	 * @param appUserDao
	 *            the appUserDao to set
	 */
	public void setAppUserDao(AppUserDao appUserDao)
	{
		this.appUserDao = appUserDao;
	}

	private <E> E doInTransaction(CallBack<? extends E> callback, boolean readonly) throws UserException
	{
		E object = null;
		DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
		TransactionStatus transactionStatus = null;
		try
		{
			transactionStatus = getTransactionManager().getTransaction(transactionDefinition);
			if (readonly)
			{
				transactionDefinition.setReadOnly(true);
			}
			object = (E) callback.execute();
			getTransactionManager().commit(transactionStatus);
		}
		catch (Exception e)
		{
			getTransactionManager().rollback(transactionStatus);
			throw new UserException(e);
		}
		return object;
	}

	public AppUser addUser(final AppUser appUser) throws UserException
	{
		return doInTransaction(new CallBack<AppUser>()
		{
			public AppUser execute() throws Exception
			{
				appUserDao.addUser(appUser);
				UserRole userRole = new UserRole();
				userRole.setRolename(RoleType.ROLE_USER.toString());
				userRole.setUserId(appUser.getUserId());
				appUserDao.addUserRole(appUser.getUserId(), userRole);
				return appUser;
			}
		}, false);
	}

	public Boolean updateUser(final AppUser appUser) throws UserException
	{
		return doInTransaction(new CallBack<Boolean>()
		{
			public Boolean execute() throws Exception
			{
				return appUserDao.updateUser(appUser);
			}
		}, false);
	}

	public Boolean activateUser(final String userId) throws UserException
	{
		return doInTransaction(new CallBack<Boolean>()
		{
			public Boolean execute() throws Exception
			{
				return appUserDao.activateUser(userId);
			}
		}, false);
	}

	public Boolean deactivateUser(final String userId) throws UserException
	{
		return doInTransaction(new CallBack<Boolean>()
		{
			public Boolean execute() throws Exception
			{
				return appUserDao.deactivateUser(userId);
			}
		}, false);
	}

	public Boolean removeUser(final String userId) throws UserException
	{
		return doInTransaction(new CallBack<Boolean>()
		{
			public Boolean execute() throws Exception
			{
				return appUserDao.removeUser(userId);
			}
		}, false);
	}

	public AppUser getUser(final String userId) throws UserException
	{
		return doInTransaction(new CallBack<AppUser>()
		{
			public AppUser execute() throws Exception
			{
				return appUserDao.getUser(userId);
			}
		}, true);
	}

	public LoginUser getUserByUserName(final String userName) throws UserException
	{
		LoginUser loginUser = doInTransaction(new CallBack<LoginUser>()
		{
			public LoginUser execute() throws Exception
			{
				LoginUser loginUser = new LoginUser();
				loginUser.setAppUser(appUserDao.getUserByUserName(userName));
				loginUser.setRoles(appUserDao.getUserRoles(loginUser.getAppUser().getUserId()));
				return loginUser;
			}
		}, true);

		return loginUser;
	}

	public LoginUser getUserById(final String userId) throws UserException
	{
		LoginUser loginUser = doInTransaction(new CallBack<LoginUser>()
		{
			public LoginUser execute() throws Exception
			{
				LoginUser loginUser = new LoginUser();
				loginUser.setAppUser(appUserDao.getUserByUserName(userId));
				loginUser.setRoles(appUserDao.getUserRoles(loginUser.getAppUser().getUserId()));
				return loginUser;
			}
		}, true);

		return loginUser;
	}

}
